home *** CD-ROM | disk | FTP | other *** search
/ CD Ware Multimedia 1995 May / cd Ware (Juegos) Epimundo.iso / DOS / C / WLIB.ZIP / WSTR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-26  |  30.8 KB  |  1,677 lines

  1. #include <stdlib.h>
  2. #include <math.h>
  3. #include <ctype.h>
  4. #include <WStr.h>
  5. #pragma hdrstop
  6.  
  7. // copyright (c) 1992, 1993 by Paul Wheaton
  8.  
  9. //.parse
  10.  
  11. /////////  BaseString class
  12.  
  13. static char GarbageChar;
  14.  
  15. char& BaseString::operator[](int Index)
  16.   {
  17.     if (Index >= Len)
  18.       {
  19.         GarbageChar=0;
  20.         return GarbageChar;
  21.       }
  22.     return P[Index];
  23.   }
  24.  
  25.   /*
  26.  
  27.   The idea here is that if a programmer were to give an index out of range
  28.   then they won't be messing up something.  If they wrote "S[5]='X'" and S
  29.   was a string of length 2, then GarbageChar would be set to 'X' and S would
  30.   be unaffected.  "MyChar=S[5]" would result in MyChar being assigned 0.
  31.  
  32.   */
  33.  
  34. //.parse
  35.  
  36. Bool BaseString::operator==(const BaseString& S) const
  37.   {
  38.     if (Len != S.Len) return No;
  39.     int I = Len/(sizeof(int));
  40.     const int* P1 = (const int*)P;
  41.     const int* P2 = (const int*)S.P;
  42.     while (I!=0)
  43.       {
  44.         if (*P1 != *P2) return No;
  45.         P1++;
  46.         P2++;
  47.         I--;
  48.       }
  49.     I= Len%(sizeof(int));
  50.     if (I!=0)
  51.       {
  52.         const char* PP1=(const char*)P1;
  53.         const char* PP2=(const char*)P2;
  54.         while (I!=0)
  55.           {
  56.             if (*PP1 != *PP2) return No;
  57.             PP1++;
  58.             PP2++;
  59.             I--;
  60.           }
  61.       }
  62.     return Yes;
  63.   }
  64.  
  65. //.parse
  66.  
  67. void BaseString::ToLower()
  68.   {
  69.     int I = Len;
  70.     char* Q = P;
  71.     while (I--) { *Q = tolower(*Q); Q++; }
  72.   }
  73.  
  74. //.parse
  75.  
  76. void BaseString::ToUpper()
  77.   {
  78.     register int I = Len;
  79.     register char* Q = P;
  80.     while (I--) { *Q = toupper(*Q); Q++; }
  81.   }
  82.  
  83. //.parse
  84.  
  85. int BaseString::Index(char SearchChar, int StartIndex) const
  86.   {
  87.     if (StartIndex>=Len) return(NotFound);
  88.     int I=StartIndex;
  89.     while ((I<Len) && (P[I]!=SearchChar)) I++;
  90.     if (I==Len) return(NotFound);
  91.     else return(I);
  92.   }
  93.  
  94. //.parse
  95.  
  96. int BaseString::Index(const char* SearchStr, int StartIndex) const
  97.   {
  98.     if (StartIndex>=Len) return(NotFound);
  99.     char* Pos=strstr(P+StartIndex,SearchStr);
  100.     if (Pos==NULL) return NotFound;
  101.     else return int(Pos-P);
  102.   }
  103.  
  104. //.parse
  105.  
  106. int BaseString::Count(char C) const
  107.   {
  108.     int Num=0;
  109.     int I;
  110.     For(I,Len) if(P[I]==C) Num++;
  111.     return Num;
  112.   }
  113.  
  114. //.parse
  115.  
  116. void BaseString::Delete(int Index,int Length)
  117.   {
  118.     // *this=BeforeSub(Index)+FromSub(Index+Length);
  119.     int S=Index+Length;
  120.     while (S<Len)
  121.       {
  122.         P[Index]=P[S];
  123.         Index++;
  124.         S++;
  125.       }
  126.     P[Index]='\0';
  127.     Len=Index;
  128.   }
  129.  
  130. //.parse
  131.  
  132. void BaseString::DeleteLast()
  133.   {
  134.     if (Len>0)
  135.       {
  136.         Len--;
  137.         P[Len]='\0';
  138.       }
  139.   }
  140.  
  141. //.parse
  142.  
  143. void BaseString::Trim()
  144.   {
  145.     if (Len==0) return;
  146.     int I=0;
  147.     while ((P[I]==' ')&&(I<Len)) I++;
  148.     if (I>0) Delete(0,I);
  149.     if (Len==0) return;
  150.     TrimTrail();
  151.   }
  152.  
  153. //.parse
  154.  
  155. void BaseString::TrimTrailTo(char C)
  156.   {
  157.     if (Len>0)
  158.       {
  159.         Len--;
  160.         while ((P[Len]!=C)&&(Len>0)) Len--;
  161.         P[Len]='\0';
  162.       }
  163.   }
  164.  
  165. //.parse
  166.  
  167. void BaseString::TrimTrail()
  168.   {
  169.     if (Len>0)
  170.       {
  171.         Len--;
  172.         while ((P[Len]==' ')&&(Len>0)) Len--;
  173.         Len++;
  174.         if ((Len==1)&&(P[0]==' ')) Len--;
  175.         P[Len]='\0';
  176.       }
  177.   }
  178.  
  179. //.parse
  180.  
  181. char BaseString::At(int Index) const
  182.   {
  183.     if (Index>=Len) return '\0';
  184.     return (P[Index]);
  185.   }
  186.  
  187. //.parse
  188.  
  189. char BaseString::Last() const
  190.   {
  191.     if (Len==0) return '\0';
  192.     else return P[Len-1];
  193.   }
  194.  
  195. //.parse
  196.  
  197. void BaseString::Clip(int NewLen)
  198.   {
  199.     if ((NewLen<Len)&&(NewLen>=0))
  200.       {
  201.         Len=NewLen;
  202.         P[Len]='\0';
  203.       }
  204.   }
  205.  
  206. //.parse
  207.  
  208. String40 BaseString::Word(int Num)
  209.   {
  210.     String40 S;
  211.     if (Len>0)
  212.       {
  213.         int LastPos=0;
  214.         int Pos=0;
  215.         int I=0;
  216.         Bool Done=False;
  217.         while (!Done)
  218.           {
  219.             Pos=Index(' ',LastPos);
  220.             if (Pos==NotFound)
  221.               {
  222.                 if (I==Num)
  223.                   {
  224.                     // functions such as "From" and "At" are not available here
  225.                     S.Len=Len-LastPos;
  226.                     if (S.Len>40) S.Len=40;
  227.                     memcpy(S.P,P+LastPos,S.Len);
  228.                     S.P[S.Len]='\0';
  229.                   }
  230.                 Done=True;
  231.               }
  232.             else
  233.               {
  234.                 if (I==Num)
  235.                   {
  236.                     S.Len=Pos-LastPos;
  237.                     if (S.Len>40) S.Len=40;
  238.                     memcpy(S.P,P+LastPos,S.Len);
  239.                     S.P[S.Len]='\0';
  240.                     Done=True;
  241.                   }
  242.                 else
  243.                   {
  244.                     I++;
  245.                     LastPos=Pos+1;
  246.                   }
  247.               }
  248.           }
  249.       }
  250.     return S;
  251.   }
  252.  
  253. //.parse
  254.  
  255. String40 BaseString::XWord(int Num)
  256.   {
  257.     String40 S;
  258.     if (Len>0)
  259.       {
  260.         int LastPos=0;
  261.         int Pos=0;
  262.         int I=0;
  263.         Bool Done=False;
  264.         while (!Done)
  265.           {
  266.             Pos=Index(' ',LastPos);
  267.             if (Pos==NotFound)
  268.               {
  269.                 if (I==Num)
  270.                   {
  271.                     S.Len=Len-LastPos;
  272.                     if (S.Len>40) S.Len=40;
  273.                     memcpy(S.P,P+LastPos,S.Len);
  274.                     S.P[S.Len]='\0';
  275.                     Delete(LastPos,S.Length());
  276.                     TrimTrail();
  277.                   }
  278.                 Done=True;
  279.               }
  280.             else
  281.               {
  282.                 if (I==Num)
  283.                   {
  284.                     int L=Pos-LastPos;
  285.                     S.Len=Pos-LastPos;
  286.                     if (S.Len>40) S.Len=40;
  287.                     memcpy(S.P,P+LastPos,S.Len);
  288.                     S.P[S.Len]='\0';
  289.                     Delete(LastPos,L+1);
  290.                     Done=True;
  291.                   }
  292.                 else
  293.                   {
  294.                     I++;
  295.                     LastPos=Pos+1;
  296.                   }
  297.               }
  298.           }
  299.       }
  300.     return S;
  301.   }
  302.  
  303. ///////////  String class
  304.  
  305. //.parse
  306.  
  307. void String::ReNew(int NewCapacity)  // replaces ANSI-C realloc
  308.   {
  309.     char* P2=(char*)malloc(NewCapacity);  // a tiny bit faster than "new"
  310.     if (P2==NULL)
  311.       {
  312.         char* E="00000 out of string mem rn";
  313.         E[4]=NewCapacity%10+'0';
  314.         NewCapacity/=10;
  315.         E[3]=NewCapacity%10+'0';
  316.         NewCapacity/=10;
  317.         E[2]=NewCapacity%10+'0';
  318.         NewCapacity/=10;
  319.         E[1]=NewCapacity%10+'0';
  320.         NewCapacity/=10;
  321.         E[0]=NewCapacity%10+'0';
  322.         NewCapacity/=10;
  323.         FatalError(E);
  324.       }
  325.     strncpy(P2,P,NewCapacity-1);
  326.     free(P);
  327.     P=P2;
  328.     P[NewCapacity-1]='\0';
  329.     if (Len>=NewCapacity) Len=NewCapacity-1;  // could have been shortened
  330.     Alloc=NewCapacity;
  331.   }
  332.  
  333. void String::New()
  334.   {
  335.     if (Alloc<16) Alloc=16;
  336.     P = (char*)malloc(Alloc);
  337.     if (P==NULL)
  338.       {
  339.         char* E="00000 out of string mem";
  340.         E[4]=Alloc%10+'0';
  341.         Alloc/=10;
  342.         E[3]=Alloc%10+'0';
  343.         Alloc/=10;
  344.         E[2]=Alloc%10+'0';
  345.         Alloc/=10;
  346.         E[1]=Alloc%10+'0';
  347.         Alloc/=10;
  348.         E[0]=Alloc%10+'0';
  349.         FatalError(E);
  350.       }
  351.   }
  352.  
  353. //.parse
  354.  
  355. String::String(const char& C, int L)
  356.   {
  357.     Len = L;
  358.     Alloc = Len + DefaultStringExtra + 1;
  359.     New();
  360.     register int I=Len;
  361.     P[I] = 0;
  362.     while (I) P[--I] = C;
  363.   }
  364.  
  365. //.parse
  366.  
  367. String::String(int Extra)
  368.   {
  369.     Len = 0;
  370.     Alloc = Extra + 1;
  371.     New();
  372.     *P='\0';
  373.   }
  374.  
  375. //.parse
  376.  
  377. String::String()
  378.   {
  379.     Len = 0;
  380.     Alloc = DefaultStringExtra + 1;
  381.     New();
  382.     *P='\0';
  383.   }
  384.  
  385. //.parse
  386.  
  387. String::String(const char* CS)
  388.   {
  389.     Len = strlen(CS);
  390.     Alloc = Len + DefaultStringExtra + 1;
  391.     New();
  392.     strcpy(P,CS);
  393.   }
  394.  
  395. //.parse
  396.  
  397. String::String(const BaseString& S)
  398.   {
  399.     Len = S.Len;
  400.     Alloc = Len + DefaultStringExtra + 1;
  401.     New();
  402.     strcpy(P,S.P);
  403.   }
  404.  
  405. //.parse
  406.  
  407. String::String(const String& S)
  408.   {
  409.     Len=S.Len;
  410.     Alloc=Len+1;
  411.     New();
  412.     strcpy(P,S.P);
  413.   }
  414.  
  415. //.parse
  416.  
  417. void String::operator=(const BaseString& S)
  418.   {
  419.     if (P == S.P) return;
  420.     Len = S.Len;
  421.     if (Len >= Alloc)
  422.       {
  423.         free(P);
  424.         Alloc = S.Alloc;
  425.         New();
  426.       }
  427.     strcpy(P,S.P);
  428.   }
  429.  
  430. //.parse
  431.  
  432. void String::operator=(const char* CS)
  433.   {
  434.     Len = strlen(CS);
  435.     if (Len >= Alloc)
  436.       {
  437.         Alloc = Len + DefaultStringExtra + 1;
  438.         free(P);
  439.         New();
  440.       }
  441.     strcpy(P,CS);
  442.   }
  443.  
  444. //.parse
  445.  
  446. void String::operator=(const char C)
  447.   {
  448.     Len=1;
  449.     P[0]=C;
  450.     P[1]='\0';
  451.   }
  452.  
  453. //.parse
  454.  
  455. String String::operator+(const String40& S) const
  456.   {
  457.     String T(Len+S.Len+1);
  458.     strcpy(T.P,P);
  459.     strcpy(&(T.P[Len]), S.P);
  460.     T.Len = Len+S.Len;
  461.     return(T);
  462.   }
  463.  
  464. //.parse
  465.  
  466. String String::operator+(const String120& S) const
  467.   {
  468.     String T(Len+S.Len+1);
  469.     strcpy(T.P,P);
  470.     strcpy(&(T.P[Len]), S.P);
  471.     T.Len = Len+S.Len;
  472.     return(T);
  473.   }
  474.  
  475. //.parse
  476.  
  477. String String::operator+(const String& S) const
  478.   {
  479.     String T(Len+S.Len+1);
  480.     strcpy(T.P,P);
  481.     strcpy(&(T.P[Len]), S.P);
  482.     T.Len = Len+S.Len;
  483.     return(T);
  484.   }
  485.  
  486. //.parse
  487.  
  488. String String::operator+(const char* CS) const
  489.   {
  490.     int CSLen = strlen(CS);
  491.     String T(Len+CSLen+1);
  492.     strcpy (T.P,P);
  493.     strcpy (&(T.P[Len]), CS);
  494.     T.Len = Len+CSLen;
  495.     return T;
  496.   }
  497.  
  498. //.parse
  499.  
  500. String String::operator+(char C) const
  501.   {
  502.     String S(Alloc+1);
  503.     S=*this;
  504.     S.P[Len]=C;
  505.     S.Len++;
  506.     S.P[S.Len]='\0';
  507.     return S;
  508.   }
  509.  
  510. //.parse
  511.  
  512. String operator+(const String40& SS, const String& S)
  513.   {
  514.     String T(SS.Length()+S.Len+1);
  515.     strcpy(T.P,(const char*)SS);
  516.     strcpy(&(T.P[SS.Length()]), S.P);
  517.     T.Len = SS.Length()+S.Len;
  518.     return(T);
  519.   }
  520.  
  521. //.parse
  522.  
  523. String operator+(const String120& SS, const String& S)
  524.   {
  525.     String T(SS.Length()+S.Len+1);
  526.     strcpy(T.P,(const char*)SS);
  527.     strcpy(&(T.P[SS.Length()]), S.P);
  528.     T.Len = SS.Length()+S.Len;
  529.     return(T);
  530.   }
  531.  
  532. //.parse
  533.  
  534. String operator+(const char* CS, const String& S)
  535.   {
  536.     int CSLen=strlen(CS);
  537.     String T(int(CSLen+S.Len+1));
  538.     strcpy(T.P,CS);
  539.     strcpy(&(T.P[CSLen]),S.P);
  540.     T.Len = CSLen + S.Len;
  541.     return T;
  542.   }
  543.  
  544. //.parse
  545.  
  546. String operator+(char C, const String& S)
  547.   {
  548.     int NewLen=S.Len+1;
  549.     String T(NewLen);
  550.     T.P[0]=C;
  551.     strcpy(&(T.P[1]),S.P);
  552.     T.Len = NewLen;
  553.     return T;
  554.   }
  555.  
  556. //.parse
  557.  
  558. void String::operator+=(const BaseString& S)
  559.   {
  560.     if (S.Len==0) return;
  561.     int NewLen=Len+S.Len;
  562.     if (Alloc <= NewLen) ReNew(NewLen+1);
  563.     strcpy(&P[Len],S.P);
  564.     Len += S.Len;
  565.   }
  566.  
  567. //.parse
  568.  
  569. void String::operator+=(const char* CS)
  570.   {
  571.     int CSLen = strlen(CS);
  572.     if (CSLen==0) return;
  573.     int NewLen=Len+CSLen;
  574.     if (Alloc <= NewLen) ReNew(NewLen+1);
  575.     strcpy(&(P[Len]),CS);
  576.     Len += CSLen;
  577.   }
  578.  
  579. //.parse
  580.  
  581. void String::operator+=(char C)
  582.   {
  583.     if (Alloc<=Len+2) ReNew(Alloc+DefaultStringExtra);
  584.     P[Len]=C;
  585.     Len++;
  586.     P[Len]='\0';
  587.     //*this=*this+C;
  588.   }
  589.  
  590. //.parse
  591.  
  592. void String::Left(int NewSize)
  593.   {
  594.     if (Len>NewSize)
  595.       {
  596.         Len=NewSize;
  597.         P[Len]=0;
  598.       }
  599.     else *this+=Spaces(NewSize-Len);
  600.   }
  601.  
  602. //.parse
  603.  
  604. void String::Right(int NewSize)
  605.   {
  606.     if (Len>NewSize)
  607.       {
  608.         Len=NewSize;
  609.         P[Len]=0;
  610.       }
  611.     else
  612.       {
  613.         String T=Spaces(NewSize-Len)+(*this);
  614.         *this=T;
  615.       }
  616.   }
  617.  
  618. //.parse
  619.  
  620. void String::Center(int NewSize)
  621.   {
  622.     if (Len>NewSize)
  623.       {
  624.         Len=NewSize;
  625.         P[Len]=0;
  626.       }
  627.     else
  628.       {
  629.         int TotSpaces=NewSize-Len;
  630.         int LeftSpaces=TotSpaces/2;
  631.         *this=Spaces(LeftSpaces)+(*this)+Spaces(TotSpaces-LeftSpaces);
  632.       }
  633.   }
  634.  
  635. //.parse
  636.  
  637. void String::Tail(int NewSize)
  638.   {
  639.     if (Len>NewSize) *this=From(Len-NewSize);
  640.     else *this=Spaces(NewSize-Len)+*this;
  641.   }
  642.  
  643. //.parse
  644.  
  645. int String::ReAlloc(int NewCapacity)
  646.   {
  647.     if (NewCapacity < Len) NewCapacity = Len;
  648.     if (Alloc != NewCapacity+1) ReNew(NewCapacity+1);
  649.     return Alloc - 1;
  650.   }
  651.  
  652. //.parse
  653.  
  654. String String::At(int Index, int Length) const
  655.   {
  656.     if (Index>=Len)
  657.       {
  658.         String S="";
  659.         return S;
  660.       }
  661.     if (Index+Length>Len) Length=Len-Index;
  662.     String S(int(Length+1));
  663.     memcpy(S.P,&P[Index],Length);
  664.     S.P[Length]='\0';
  665.     S.Len=Length;
  666.     return S;
  667.   }
  668.  
  669. //.parse
  670.  
  671. void String::Insert(char C,int Index)
  672.   {
  673.     if (Index<0) Index=0;
  674.     if ((Len+2)>Alloc) ReNew(Alloc+DefaultStringExtra+1);
  675.     if (Index>=Len)
  676.       {
  677.         P[Len]=C;
  678.         P[Len+1]='\0';
  679.       }
  680.     else
  681.       {
  682.         memmove(P+Index+1,P+Index,Len-Index+1);
  683.         P[Index]=C;
  684.       }
  685.     Len++;
  686.   }
  687.  
  688. void String::Insert(const char* St,int Index)
  689.   {
  690.     if (Index<0) Index=0;
  691.     int SLen=strlen(St);
  692.     if (SLen>0)
  693.       {
  694.         if ((Len+SLen)>=Alloc) ReNew(Alloc+DefaultStringExtra+SLen);
  695.         if (Index>=Len) strcpy(P+Len,St);
  696.         else
  697.           {
  698.             memmove(P+Index+SLen,P+Index,Len-Index+1);
  699.             memcpy(P+Index,St,SLen);
  700.           }
  701.         Len+=SLen;
  702.       }
  703.     //*this=Before(Index)+St+From(Index);
  704.   }
  705.  
  706. ////////  StackString class
  707.  
  708. //.parse
  709.  
  710. void StackString::operator=(const BaseString& S)
  711.   {
  712.     if (P == S.P) return;
  713.     Len = Min(S.Len,Alloc-1);
  714.     memcpy(P,S.P,Len);
  715.     P[Len]='\0';
  716.   }
  717.  
  718. //.parse
  719.  
  720. void StackString::operator=(const char* CS)
  721.   {
  722.     Len = Min(int(strlen(CS)),Alloc-1);
  723.     memcpy(P,CS,Len);
  724.     P[Len]='\0';
  725.   }
  726.  
  727. void StackString::operator=(const char C)
  728.   {
  729.     Len=1;
  730.     P[0]=C;
  731.   }
  732.  
  733. //.parse
  734.  
  735. void StackString::operator+=(const BaseString& S)
  736.   {
  737.     if (S.Len==0) return;
  738.     int MaxCopy=Alloc-Len-1;
  739.     int CopyLen=Min(MaxCopy,S.Len);
  740.     memcpy(&P[Len],S.P,CopyLen);
  741.     Len+=CopyLen;
  742.     P[Len]='\0';
  743.   }
  744.  
  745. //.parse
  746.  
  747. void StackString::operator+=(const char* CS)
  748.   {
  749.     int CSLen = strlen(CS);
  750.     if (CSLen==0) return;
  751.     int MaxCopy=Alloc-Len-1;
  752.     int CopyLen=Min(MaxCopy,CSLen);
  753.     memcpy(&P[Len],CS,CopyLen);
  754.     Len+=CopyLen;
  755.     P[Len]='\0';
  756.   }
  757.  
  758. //.parse
  759.  
  760. void StackString::operator+=(char C)
  761.   {
  762.     if (Len<(Alloc-1))
  763.       {
  764.         P[Len]=C;
  765.         Len++;
  766.         P[Len]='\0';
  767.       }
  768.   }
  769.  
  770. //.parse
  771.  
  772. void StackString::Left(int NewSize)
  773.   {
  774.     if (Len>NewSize)
  775.       {
  776.         Len=NewSize;
  777.         P[Len]=0;
  778.       }
  779.     else if (NewSize>Len)
  780.       {
  781.         int End=Min(NewSize,Alloc-1);
  782.         int Dif=End-Len;
  783.         if (Dif>0)
  784.           {
  785.             memset(P+Len,' ',Dif);
  786.             Len+=Dif;
  787.             P[Len]='\0';
  788.           }
  789.       }
  790.   }
  791.  
  792. //.parse
  793.  
  794. void StackString::Right(int NewSize)
  795.   {
  796.     if (Len>NewSize)
  797.       {
  798.         Len=NewSize;
  799.         P[Len]=0;
  800.       }
  801.     else if (NewSize>Len)
  802.       {
  803.         int End=Min(NewSize,Alloc-1);
  804.         int Dif=End-Len;
  805.         memmove(P+Dif,P,Len);
  806.         memset(P,' ',Dif);
  807.         Len+=Dif;
  808.         P[Len]='\0';
  809.       }
  810.   }
  811.  
  812. //.parse
  813.  
  814. void StackString::Center(int NewSize)
  815.   {
  816.     if (Len>NewSize)
  817.       {
  818.         Len=NewSize;
  819.         P[Len]=0;
  820.       }
  821.     else
  822.       {
  823.         NewSize=Min(NewSize,Alloc-1);
  824.         Right(((NewSize-Len)/2)+Len);
  825.         Left(NewSize);
  826.       }
  827.   }
  828.  
  829. //.parse
  830.  
  831. void StackString::Tail(int NewSize)
  832.   {
  833.     if (Len>NewSize)
  834.       {
  835.         memmove(P,P+(Len-NewSize),NewSize);
  836.         Len=NewSize;
  837.         P[Len]='\0';
  838.       }
  839.     else Right(NewSize);
  840.   }
  841.  
  842. //.parse
  843.  
  844. void StackString::Sub(StackString& D, int I, int L)
  845.   {
  846.     if ((I+L)>Len) L=Len-I;
  847.     D.Len=L;
  848.     memcpy(D.P,P+I,L);
  849.     D.P[L]='\0';
  850.   }
  851.  
  852. //.parse
  853.  
  854. void StackString::Insert(char C,int Index)
  855.   {
  856.     if ((Len==Alloc-1)&&(Index<Len)) Len--;
  857.     if (Index>=Len)
  858.       {
  859.         P[Len]=C;
  860.         Len++;
  861.       }
  862.     else
  863.       {
  864.         memmove(P+Index+1,P+Index,Len-Index+1);
  865.         P[Index]=C;
  866.         Len++;
  867.       }
  868.     P[Len]='\0';
  869.   }
  870.  
  871. //.parse
  872.  
  873. void StackString::Insert(const char* St,int Index)
  874.   {
  875.     int StLen=strlen(St);
  876.     if (Index>Len) Index=Len;
  877.     int MoveNum=Len-Index;
  878.     int TotLen=StLen+Len;
  879.     int Excess=TotLen-(Alloc-1);
  880.     if (Excess>0)
  881.       {
  882.         MoveNum-=Excess;
  883.         if (MoveNum<0) StLen+=MoveNum;
  884.       }
  885.     if (MoveNum>0)
  886.       {
  887.         memmove(P+Index+StLen,P+Index,MoveNum);
  888.         Len+=MoveNum;
  889.       }
  890.     if (StLen>0)
  891.       {
  892.         memcpy(P+Index,St,StLen);
  893.         Len+=StLen;
  894.       }
  895.     P[Len]='\0';
  896.   }
  897.  
  898. ///////  String40 class
  899.  
  900. //.parse
  901.  
  902. String40::String40()
  903.   {
  904.     P=&Buf[0];
  905.     Buf[0]='\0';
  906.     Len=0;
  907.     Alloc=41;
  908.   }
  909.  
  910. //.parse
  911.  
  912. String40::String40(const char& C, int L)
  913.   {
  914.     P=&Buf[0];
  915.     Alloc=41;
  916.     Len=L;
  917.     if (Len>40) Len=40;
  918.     memset(P,C,Len);
  919.     Buf[Len]='\0';
  920.   }
  921.  
  922. //.parse
  923.  
  924. String40::String40(const char* CS)
  925.   {
  926.     P=&Buf[0];
  927.     Alloc=41;
  928.     Len=strlen(CS);
  929.     if (Len>40) Len=40;
  930.     memcpy(P,CS,Len);
  931.     Buf[Len]='\0';
  932.   }
  933.  
  934. //.parse
  935.  
  936. String40::String40(const BaseString& BS)
  937.   {
  938.     P=&Buf[0];
  939.     Alloc=41;
  940.     Len=BS.Len;
  941.     if (Len>40) Len=40;
  942.     memcpy(P,BS.P,Len);
  943.     Buf[Len]='\0';
  944.   }
  945.  
  946. //.parse
  947.  
  948. String40::String40(const String40& S)
  949.   {
  950.     P=&Buf[0];
  951.     Alloc=41;
  952.     Len=S.Len;
  953.     strcpy(P,S.P);
  954.   }
  955.  
  956. //.parse
  957.  
  958. String40 String40::operator+(const String40& S) const
  959.   {
  960.     String40 T(*this);
  961.     T+=S;
  962.     return T;
  963.   }
  964.  
  965. //.parse
  966.  
  967. String40 String40::operator+(const char* S) const
  968.   {
  969.     String40 T(*this);
  970.     T+=S;
  971.     return T;
  972.   }
  973.  
  974. //.parse
  975.  
  976. String40 String40::operator+(char C) const
  977.   {
  978.     String40 T(*this);
  979.     T+=C;
  980.     return T;
  981.   }
  982.  
  983. //.parse
  984.  
  985. String40 operator+(const char* S1, const String40& S2)
  986.   {
  987.     String40 T(S1);
  988.     T+=S2;
  989.     return T;
  990.   }
  991.  
  992. //.parse
  993.  
  994. String40 operator+(char C, const String40& S)
  995.   {
  996.     String40 T(C);
  997.     T+=S;
  998.     return T;
  999.   }
  1000.  
  1001. //.parse
  1002.  
  1003. String40 String40::At(int Index, int Length) const
  1004.   {
  1005.     String40 T;
  1006.     StackString::Sub(T,Index,Length);
  1007.     return T;
  1008.   }
  1009.  
  1010. ///////  String120 class
  1011.  
  1012. //.parse
  1013.  
  1014. String120::String120()
  1015.   {
  1016.     P=&Buf[0];
  1017.     Buf[0]='\0';
  1018.     Len=0;
  1019.     Alloc=121;
  1020.   }
  1021.  
  1022. //.parse
  1023.  
  1024. String120::String120(const char& C, int L)
  1025.   {
  1026.     P=&Buf[0];
  1027.     Alloc=121;
  1028.     Len=L;
  1029.     if (Len>120) Len=120;
  1030.     memset(P,C,Len);
  1031.     Buf[Len]='\0';
  1032.   }
  1033.  
  1034. //.parse
  1035.  
  1036. String120::String120(const char* CS)
  1037.   {
  1038.     P=&Buf[0];
  1039.     Alloc=121;
  1040.     Len=strlen(CS);
  1041.     if (Len>120) Len=120;
  1042.     memcpy(P,CS,Len);
  1043.     Buf[Len]='\0';
  1044.   }
  1045.  
  1046. //.parse
  1047.  
  1048. String120::String120(const BaseString& BS)
  1049.   {
  1050.     P=&Buf[0];
  1051.     Alloc=121;
  1052.     Len=BS.Len;
  1053.     if (Len>120) Len=120;
  1054.     memcpy(P,BS.P,Len);
  1055.     Buf[Len]='\0';
  1056.   }
  1057.  
  1058. //.parse
  1059.  
  1060. String120::String120(const String120& S)
  1061.   {
  1062.     P=&Buf[0];
  1063.     Alloc=121;
  1064.     Len=S.Len;
  1065.     strcpy(P,S.P);
  1066.   }
  1067.  
  1068. //.parse
  1069.  
  1070. String120 String120::operator+(const String40& S) const
  1071.   {
  1072.     String120 T(*this);
  1073.     T+=S;
  1074.     return T;
  1075.   }
  1076.  
  1077. //.parse
  1078.  
  1079. String120 String120::operator+(const String120& S) const
  1080.   {
  1081.     String120 T(*this);
  1082.     T+=S;
  1083.     return T;
  1084.   }
  1085.  
  1086. //.parse
  1087.  
  1088. String120 String120::operator+(const char* S) const
  1089.   {
  1090.     String120 T(*this);
  1091.     T+=S;
  1092.     return T;
  1093.   }
  1094.  
  1095. //.parse
  1096.  
  1097. String120 String120::operator+(char C) const
  1098.   {
  1099.     String120 T(*this);
  1100.     T+=C;
  1101.     return T;
  1102.   }
  1103.  
  1104. //.parse
  1105.  
  1106. String120 operator+(const String40& S1, const String120& S2)
  1107.   {
  1108.     String120 T(S1);
  1109.     T+=S2;
  1110.     return T;
  1111.   }
  1112.  
  1113. //.parse
  1114.  
  1115. String120 operator+(const char* S1, const String120& S2)
  1116.   {
  1117.     String120 T(S1);
  1118.     T+=S2;
  1119.     return T;
  1120.   }
  1121.  
  1122. //.parse
  1123.  
  1124. String120 operator+(char C, const String120& S)
  1125.   {
  1126.     String120 T(C);
  1127.     T+=S;
  1128.     return T;
  1129.   }
  1130.  
  1131. //.parse
  1132.  
  1133. String120 String120::At(int Index, int Length) const
  1134.   {
  1135.     String120 T;
  1136.     StackString::Sub(T,Index,Length);
  1137.     return T;
  1138.   }
  1139.  
  1140. //.parse
  1141.  
  1142. String CenterText(const char* CS, int NewSize)
  1143.   {
  1144.     String S=CS;
  1145.     S.Center(NewSize);
  1146.     return S;
  1147.   }
  1148.  
  1149. //.parse
  1150.  
  1151. String40 Form(int FLen,SLong Val)
  1152.   {
  1153.     String40 Mask=TailText("##,###,###,###",FLen);
  1154.       //  SLong has 10 significant digits + 1 sign digit
  1155.     if (Mask[0]==',') Mask[0]='#';
  1156.     String40 ReturnString=Form(Mask,double(Val));
  1157.     return ReturnString;
  1158.   }
  1159.  
  1160. //.parse
  1161.  
  1162. static Bool DigitToken(char C)
  1163.   {
  1164.     return ((C=='@') || (C=='#'));
  1165.   }
  1166.  
  1167. static void FindDigitToken(String40& S, int &I)
  1168.   {
  1169.     while (!DigitToken(S[I])) I++;
  1170.   }
  1171.  
  1172. static void DoFillers(String40& Mask, int Fillers)
  1173.   {
  1174.     int I=0;
  1175.     while (Fillers)
  1176.       {
  1177.         FindDigitToken(Mask,I);
  1178.         if (Mask[I]=='@') Mask[I]='0';
  1179.         else Mask[I]=' ';
  1180.         Fillers--;
  1181.       }
  1182.   }
  1183.  
  1184. static void DoSpaceFillers(String40& Mask, int Fillers)
  1185.   {
  1186.     int I=0;
  1187.     FindDigitToken(Mask,I);
  1188.     while (Fillers)
  1189.       {
  1190.         if (Mask[I]=='#') Fillers--;
  1191.         Mask[I]=' ';
  1192.         I++;
  1193.       }
  1194.     if (Mask[I]==',') Mask[I]=' ';
  1195.   }
  1196.  
  1197. static void DoNeg(String40& Mask)
  1198.   {
  1199.     int I=0;
  1200.     FindDigitToken(Mask,I);
  1201.     if (Mask[I+1]==',')
  1202.       {
  1203.         Mask[I]=' ';
  1204.         I++;
  1205.       }
  1206.     Mask[I]='-';
  1207.   }
  1208.  
  1209. String40 Form(const char* M,double Val)
  1210.   {
  1211.     String40 Mask=M;
  1212.     Bool Negative=(Val<0.0);
  1213.     Val=Abs(Val);
  1214.     int MaskDecPos=Mask.Index('.'); //  The position of the decimal in Mask
  1215.     int MI;  //  Mask Index:  the part of the mask currently being fooled with
  1216.     String40 DecStr="";
  1217.     if (MaskDecPos!=NotFound)
  1218.       {
  1219.         int Digits=0;
  1220.         for(MI=MaskDecPos+1;MI<Mask.Length();MI++)
  1221.           {
  1222.             if (Mask[MI]=='#') Mask[MI]='@';
  1223.             if (Mask[MI]=='@') Digits++;
  1224.           }
  1225.         MI=MaskDecPos+1;
  1226.         double D=(Val-floor(Val));
  1227.         Val-=D;
  1228.         double Mult=pow(10,Digits);
  1229.         D*=Mult;
  1230.         if (D+0.5>Mult)
  1231.           {
  1232.             D=0.0;
  1233.             Val+=1.0;
  1234.           }
  1235.         DecStr=Form(Mask.From(MI),D);
  1236.           //  recursive call!  This part will be skipped cuz there's no decimal in the mask
  1237.         Mask.Left(MI);  //  chop off decimal portion
  1238.       }
  1239.     int Digits=0;  // the number of digits there are available to fill
  1240.     For(MI,Mask.Length())
  1241.         if (DigitToken(Mask[MI])) Digits++;
  1242.     String40 IStr=DStr(Val+0.5);  //  convert the integral part to a string
  1243.     Bool NegBrackets=(Mask[0]=='<');
  1244.     Bool NegCharNeeded=((!NegBrackets)&&(Negative));
  1245.     if (NegCharNeeded) Digits--;
  1246.     if (IStr.Length()>Digits)  // then fill with *'s
  1247.       {
  1248.         For(MI,Mask.Length())
  1249.             if (DigitToken(Mask[MI])) Mask[MI]='*';
  1250.       }
  1251.     else
  1252.       {
  1253.         int Fillers=Digits-IStr.Length();
  1254.         MI=0;
  1255.         FindDigitToken(Mask,MI);
  1256.         if (Mask[MI]=='#')
  1257.           {
  1258.             DoSpaceFillers(Mask,Fillers);
  1259.             if (NegCharNeeded) DoNeg(Mask);
  1260.           }
  1261.         else
  1262.           {
  1263.             if (NegCharNeeded) DoNeg(Mask);
  1264.             DoFillers(Mask,Fillers);
  1265.           }
  1266.         int I;  //  IStr Index
  1267.         For(I,IStr.Length())
  1268.           {
  1269.             FindDigitToken(Mask,MI);
  1270.             Mask[MI]=IStr[I];
  1271.           }
  1272.       }
  1273.     Mask+=DecStr;
  1274.     if (NegBrackets && (!Negative))
  1275.       {
  1276.         Mask[0]=' ';
  1277.         Mask[Mask.Length()-1]=' ';
  1278.       }
  1279.     return (Mask);
  1280.   }
  1281.  
  1282. //.parse
  1283.  
  1284. String40 Form(int FLen,const double& Val)
  1285.   {
  1286.     String40 Mask=TailText("#,###,###,###",FLen);
  1287.       //  SLong has 10 significant digits
  1288.     if (Mask[0]==',') Mask[0]='#';
  1289.     String40 ReturnString=Form(Mask,Val);
  1290.     return ReturnString;
  1291.   }
  1292.  
  1293. //.parse
  1294.  
  1295. String40 Form(int FLen,const Long& Val)
  1296.   {return Form(FLen,float(Val));}
  1297.  
  1298. String40 Form(int FLen,const float& Val)
  1299.   {
  1300.     return Form(int(FLen),double(Val));
  1301.   }
  1302.  
  1303. #ifndef MAJORBBS
  1304. String40 HexStr(Long Num)
  1305.   {
  1306.     char TmpStr[35];
  1307.     ltoa(Num,TmpStr,16);
  1308.     String40 X=TmpStr;
  1309.     return(X);
  1310.   }
  1311. #endif
  1312.  
  1313. //.parse
  1314.  
  1315. String LeftText(const char* CS, int NewSize)
  1316.   {
  1317.     String S=CS;
  1318.     S.Left(NewSize);
  1319.     return(S);
  1320.   }
  1321.  
  1322. #ifndef MAJORBBS
  1323. String40 OctalStr(Long Num)
  1324.   {
  1325.     char TmpStr[35];
  1326.     ltoa(Num,TmpStr,8);
  1327.     String40 X=TmpStr;
  1328.     return(X);
  1329.   }
  1330. #endif
  1331.  
  1332. //.parse
  1333.  
  1334. String StringOf(int HowMany, char What)
  1335.  {
  1336.    String S(What,HowMany);
  1337.    return(S);
  1338.  }
  1339.  
  1340. //.parse
  1341.  
  1342. String40 Str(long Num)
  1343.   {
  1344.     const BuffyLen=13;
  1345.     char Buffy[BuffyLen]="           0";
  1346.     char* BuffyPos=&Buffy[BuffyLen-2];
  1347.     Bool Neg=False;
  1348.     if (Num<0)
  1349.       {
  1350.         Neg=True;
  1351.         Num=-Num;
  1352.       }
  1353.     if (Num>0)
  1354.       {
  1355.         while (Num>0)
  1356.           {
  1357.             *BuffyPos=char((Num%10)+48);
  1358.             Num/=10;
  1359.             BuffyPos--;
  1360.           }
  1361.         BuffyPos++;
  1362.         if (Neg)
  1363.           {
  1364.             BuffyPos--;
  1365.             *BuffyPos='-';
  1366.           }
  1367.       }
  1368.     return String40(BuffyPos);
  1369.   }
  1370.  
  1371. //.parse
  1372.  
  1373. String40 CommaStr(long Num)
  1374.   {
  1375.     const BuffyLen=15;
  1376.     char Buffy[BuffyLen]=",,,,,,,,,,,,,0";
  1377.     int I=0;
  1378.     char* BuffyPos=&Buffy[BuffyLen-2];
  1379.     while (Num>0)
  1380.       {
  1381.         *BuffyPos=char((Num%10)+48);
  1382.         Num/=10;
  1383.         BuffyPos--;
  1384.         I++;
  1385.         if (I%3==0) BuffyPos--;
  1386.       }
  1387.     BuffyPos++;
  1388.     if (*BuffyPos==',') BuffyPos++;
  1389.     return String40(BuffyPos);
  1390.   }
  1391.  
  1392. //.parse
  1393.  
  1394. String RightText(const char* CS, int NewSize)
  1395.   {
  1396.     String S=CS;
  1397.     S.Right(NewSize);
  1398.     return S;
  1399.   }
  1400.  
  1401. //.parse
  1402.  
  1403. String TailText(const char* CS, int NewSize)
  1404.   {
  1405.     String S=CS;
  1406.     S.Tail(NewSize);
  1407.     return S;
  1408.   }
  1409.  
  1410. //.parse
  1411.  
  1412. String Trim(const char* S)
  1413.   {
  1414.     String St=S;
  1415.     St.Trim();
  1416.     return St;
  1417.   }
  1418.  
  1419. //.parse
  1420.  
  1421. String TrimTrail(const char* S)
  1422.   {
  1423.     String St=S;
  1424.     St.TrimTrail();
  1425.     return St;
  1426.   }
  1427.  
  1428. //.parse
  1429.  
  1430. String40 DStr(double Num)
  1431.   {
  1432.     Bool Sign=(Num<(-0.0000000000001));
  1433.     if (Sign) Num=-Num;
  1434.     double N=floor(Num);
  1435.     String40 S;
  1436.     while (N>0.1)
  1437.       {
  1438.         N/=10.0;
  1439.         double D=(N-floor(N));
  1440.         S=char(Round(D*10.0)+48)+S;
  1441.         N-=D;
  1442.       }
  1443.     if (Sign) S='-'+S;
  1444.     if (S.Length()==0) S='0';
  1445.     return(S);
  1446.   }
  1447.  
  1448. //.parse
  1449.  
  1450. String Spaces(int HowMany)
  1451.  {
  1452.    String S(' ',HowMany);
  1453.    return(S);
  1454.  }
  1455.  
  1456. //.parse
  1457.  
  1458. void String::Replace(const char* SearchStr, const char* ReplaceStr)
  1459.   {
  1460.     int SLen=strlen(SearchStr);
  1461.     int RLen=strlen(ReplaceStr);
  1462.     Bool SameLen=(SLen==RLen);
  1463.     int Pos=0;
  1464.     while((Pos=Index(SearchStr,Pos))!=NotFound)
  1465.       {
  1466.         if (SameLen)
  1467.           {
  1468.             int I;
  1469.             For(I,SLen) P[Pos+I]=ReplaceStr[I];
  1470.           }
  1471.         else if (SLen>RLen)
  1472.           {
  1473.             Delete(Pos,SLen-RLen);
  1474.             int I;
  1475.             For(I,RLen) P[Pos+I]=ReplaceStr[I];
  1476.           }
  1477.         else
  1478.           {
  1479.             int I;
  1480.             For(I,SLen) P[Pos+I]=ReplaceStr[I];
  1481.             Insert(&ReplaceStr[SLen],Pos+SLen);
  1482.           }
  1483.       }
  1484.   }
  1485.  
  1486. //.parse
  1487.  
  1488. void String::Replace(const char SearchChar, const char* ReplaceStr)
  1489.   {
  1490.     int RLen=strlen(ReplaceStr);
  1491.     int Pos=0;
  1492.     while((Pos=Index(SearchChar,Pos))!=NotFound)
  1493.       {
  1494.         if (RLen>1)
  1495.           {
  1496.             P[Pos]=*ReplaceStr;
  1497.             Insert(&ReplaceStr[1],Pos+1);
  1498.           }
  1499.         if (RLen==1) P[Pos]=*ReplaceStr;
  1500.         else Delete(Pos);
  1501.       }
  1502.   }
  1503.  
  1504. //.parse
  1505.  
  1506. void String::Replace(const char* SearchStr, const char ReplaceChar)
  1507.   {
  1508.     int SLen=strlen(SearchStr);
  1509.     int Pos=0;
  1510.     while((Pos=Index(SearchStr,Pos))!=NotFound)
  1511.       {
  1512.         if (SLen>1)
  1513.           {
  1514.             Delete(Pos,SLen-1);
  1515.             P[Pos]=ReplaceChar;
  1516.           }
  1517.         else P[Pos]=ReplaceChar;
  1518.       }
  1519.   }
  1520.  
  1521. //.parse
  1522.  
  1523. void String::Replace(const char SearchChar, const char ReplaceChar)
  1524.   {
  1525.     int Pos=0;
  1526.     while((Pos=Index(SearchChar,Pos))!=NotFound) P[Pos]=ReplaceChar;
  1527.   }
  1528.  
  1529. //.parse
  1530.  
  1531. void String120::Replace(const char* SearchStr, const char* ReplaceStr)
  1532.   {
  1533.     int SLen=strlen(SearchStr);
  1534.     int RLen=strlen(ReplaceStr);
  1535.     Bool SameLen=(SLen==RLen);
  1536.     int Pos=0;
  1537.     while((Pos=Index(SearchStr,Pos))!=NotFound)
  1538.       {
  1539.         if (SameLen)
  1540.           {
  1541.             int I;
  1542.             For(I,SLen) P[Pos+I]=ReplaceStr[I];
  1543.           }
  1544.         else if (SLen>RLen)
  1545.           {
  1546.             Delete(Pos,SLen-RLen);
  1547.             int I;
  1548.             For(I,RLen) P[Pos+I]=ReplaceStr[I];
  1549.           }
  1550.         else
  1551.           {
  1552.             int I;
  1553.             For(I,SLen) P[Pos+I]=ReplaceStr[I];
  1554.             Insert(&ReplaceStr[SLen],Pos+SLen);
  1555.           }
  1556.       }
  1557.   }
  1558.  
  1559. //.parse
  1560.  
  1561. void String120::Replace(const char SearchChar, const char* ReplaceStr)
  1562.   {
  1563.     int RLen=strlen(ReplaceStr);
  1564.     int Pos=0;
  1565.     while((Pos=Index(SearchChar,Pos))!=NotFound)
  1566.       {
  1567.         if (RLen>1)
  1568.           {
  1569.             P[Pos]=*ReplaceStr;
  1570.             Insert(&ReplaceStr[1],Pos+1);
  1571.           }
  1572.         if (RLen==1) P[Pos]=*ReplaceStr;
  1573.         else Delete(Pos);
  1574.       }
  1575.   }
  1576.  
  1577. //.parse
  1578.  
  1579. void String120::Replace(const char* SearchStr, const char ReplaceChar)
  1580.   {
  1581.     int SLen=strlen(SearchStr);
  1582.     int Pos=0;
  1583.     while((Pos=Index(SearchStr,Pos))!=NotFound)
  1584.       {
  1585.         if (SLen>1)
  1586.           {
  1587.             Delete(Pos,SLen-1);
  1588.             P[Pos]=ReplaceChar;
  1589.           }
  1590.         else P[Pos]=ReplaceChar;
  1591.       }
  1592.   }
  1593.  
  1594. //.parse
  1595.  
  1596. void String120::Replace(const char SearchChar, const char ReplaceChar)
  1597.   {
  1598.     int Pos=0;
  1599.     while((Pos=Index(SearchChar,Pos))!=NotFound) P[Pos]=ReplaceChar;
  1600.   }
  1601.  
  1602. //.parse
  1603.  
  1604. void String40::Replace(const char* SearchStr, const char* ReplaceStr)
  1605.   {
  1606.     int SLen=strlen(SearchStr);
  1607.     int RLen=strlen(ReplaceStr);
  1608.     Bool SameLen=(SLen==RLen);
  1609.     int Pos=0;
  1610.     while((Pos=Index(SearchStr,Pos))!=NotFound)
  1611.       {
  1612.         if (SameLen)
  1613.           {
  1614.             int I;
  1615.             For(I,SLen) P[Pos+I]=ReplaceStr[I];
  1616.           }
  1617.         else if (SLen>RLen)
  1618.           {
  1619.             Delete(Pos,SLen-RLen);
  1620.             int I;
  1621.             For(I,RLen) P[Pos+I]=ReplaceStr[I];
  1622.           }
  1623.         else
  1624.           {
  1625.             int I;
  1626.             For(I,SLen) P[Pos+I]=ReplaceStr[I];
  1627.             Insert(&ReplaceStr[SLen],Pos+SLen);
  1628.           }
  1629.       }
  1630.   }
  1631.  
  1632. //.parse
  1633.  
  1634. void String40::Replace(const char SearchChar, const char* ReplaceStr)
  1635.   {
  1636.     int RLen=strlen(ReplaceStr);
  1637.     int Pos=0;
  1638.     while((Pos=Index(SearchChar,Pos))!=NotFound)
  1639.       {
  1640.         if (RLen>1)
  1641.           {
  1642.             P[Pos]=*ReplaceStr;
  1643.             Insert(&ReplaceStr[1],Pos+1);
  1644.           }
  1645.         if (RLen==1) P[Pos]=*ReplaceStr;
  1646.         else Delete(Pos);
  1647.       }
  1648.   }
  1649.  
  1650. //.parse
  1651.  
  1652. void String40::Replace(const char* SearchStr, const char ReplaceChar)
  1653.   {
  1654.     int SLen=strlen(SearchStr);
  1655.     int Pos=0;
  1656.     while((Pos=Index(SearchStr,Pos))!=NotFound)
  1657.       {
  1658.         if (SLen>1)
  1659.           {
  1660.             Delete(Pos,SLen-1);
  1661.             P[Pos]=ReplaceChar;
  1662.           }
  1663.         else P[Pos]=ReplaceChar;
  1664.       }
  1665.   }
  1666.  
  1667. //.parse
  1668.  
  1669. void String40::Replace(const char SearchChar, const char ReplaceChar)
  1670.   {
  1671.     int Pos=0;
  1672.     while((Pos=Index(SearchChar,Pos))!=NotFound) P[Pos]=ReplaceChar;
  1673.   }
  1674.  
  1675.  
  1676.  
  1677.